home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 34 / Amiga Format CD34 (1998-11-20)(Future Publishing)(GB)[!][Christmas issue].iso / -seriously_amiga- / programming / c / mesa-2.6 / src-glu / mipmap.c < prev    next >
C/C++ Source or Header  |  1998-10-01  |  18KB  |  730 lines

  1. /* $Id: mipmap.c,v 1.5 1997/07/24 01:28:44 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  2.4
  6.  * Copyright (C) 1995-1997  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * mipmap.c
  26.  *
  27.  * Version 1.0  27 Jun 1998
  28.  * by Jarno van der Linden
  29.  * jarno@kcbbs.gen.nz
  30.  *
  31.  * File created from mipmap.c ver 1.5 and glu.h ver 1.9 using GenProtos
  32.  *
  33.  */
  34.  
  35.  
  36. #ifdef PC_HEADER
  37. #include "all.h"
  38. #else
  39. #include <assert.h>
  40. #include <math.h>
  41. #include <stdio.h>
  42. #include <stdlib.h>
  43. #include "gluP.h"
  44. #endif
  45.  
  46.  
  47. /*
  48.  * Compute ceiling of integer quotient of A divided by B:
  49.  */
  50. #define CEILING( A, B )  ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 )
  51.  
  52.  
  53.  
  54. #ifdef EPSILON
  55. #undef EPSILON
  56. #endif
  57. #define EPSILON 0.001
  58.  
  59.  
  60. /* To work around optimizer bug in MSVC4.1 */
  61. #ifdef __WIN32__
  62. void dummy(GLuint j, GLuint k){
  63. }
  64. #else
  65. #define dummy(J, K)
  66. #endif
  67.  
  68.  
  69. __asm __saveds GLint APIENTRY gluScaleImage( register __d0 GLenum format,
  70.                                              register __d1 GLint widthin, register __d2 GLint heightin,
  71.                                              register __d3 GLenum typein, register __a0 const void *datain,
  72.                                              register __d4 GLint widthout, register __d5 GLint heightout,
  73.                                              register __d6 GLenum typeout, register __a1 void *dataout )
  74. {
  75.    GLint components, i, j, k;
  76.    GLfloat *tempin, *tempout;
  77.    GLfloat sx, sy;
  78.    GLint unpackrowlength, unpackalignment, unpackskiprows, unpackskippixels;
  79.    GLint packrowlength, packalignment, packskiprows, packskippixels;
  80.    GLint sizein, sizeout;
  81.    GLint rowstride, rowlen;
  82.  
  83.  
  84.    /* Determine number of components per pixel */
  85.    switch (format) {
  86.       case GL_COLOR_INDEX:
  87.       case GL_STENCIL_INDEX:
  88.       case GL_DEPTH_COMPONENT:
  89.       case GL_RED:
  90.       case GL_GREEN:
  91.       case GL_BLUE:
  92.       case GL_ALPHA:
  93.       case GL_LUMINANCE:
  94.          components = 1;
  95.      break;
  96.       case GL_LUMINANCE_ALPHA:
  97.      components = 2;
  98.      break;
  99.       case GL_RGB:
  100.      components = 3;
  101.      break;
  102.       case GL_RGBA:
  103.      components = 4;
  104.      break;
  105.       default:
  106.      return GLU_INVALID_ENUM;
  107.    }
  108.  
  109.    /* Determine bytes per input datum */
  110.    switch (typein) {
  111.       case GL_UNSIGNED_BYTE:    sizein = sizeof(GLubyte);    break;
  112.       case GL_BYTE:        sizein = sizeof(GLbyte);    break;
  113.       case GL_UNSIGNED_SHORT:    sizein = sizeof(GLushort);    break;
  114.       case GL_SHORT:        sizein = sizeof(GLshort);    break;
  115.       case GL_UNSIGNED_INT:    sizein = sizeof(GLuint);    break;
  116.       case GL_INT:        sizein = sizeof(GLint);        break;
  117.       case GL_FLOAT:        sizein = sizeof(GLfloat);    break;
  118.       case GL_BITMAP:
  119.      /* not implemented yet */
  120.       default:
  121.      return GL_INVALID_ENUM;
  122.    }
  123.  
  124.    /* Determine bytes per output datum */
  125.    switch (typeout) {
  126.       case GL_UNSIGNED_BYTE:    sizeout = sizeof(GLubyte);    break;
  127.       case GL_BYTE:        sizeout = sizeof(GLbyte);    break;
  128.       case GL_UNSIGNED_SHORT:    sizeout = sizeof(GLushort);    break;
  129.       case GL_SHORT:        sizeout = sizeof(GLshort);    break;
  130.       case GL_UNSIGNED_INT:    sizeout = sizeof(GLuint);    break;
  131.       case GL_INT:        sizeout = sizeof(GLint);    break;
  132.       case GL_FLOAT:        sizeout = sizeof(GLfloat);    break;
  133.       case GL_BITMAP:
  134.      /* not implemented yet */
  135.       default:
  136.      return GL_INVALID_ENUM;
  137.    }
  138.  
  139.    /* Get glPixelStore state */
  140.    glGetIntegerv( GL_UNPACK_ROW_LENGTH, &unpackrowlength );
  141.    glGetIntegerv( GL_UNPACK_ALIGNMENT, &unpackalignment );
  142.    glGetIntegerv( GL_UNPACK_SKIP_ROWS, &unpackskiprows );
  143.    glGetIntegerv( GL_UNPACK_SKIP_PIXELS, &unpackskippixels );
  144.    glGetIntegerv( GL_PACK_ROW_LENGTH, &packrowlength );
  145.    glGetIntegerv( GL_PACK_ALIGNMENT, &packalignment );
  146.    glGetIntegerv( GL_PACK_SKIP_ROWS, &packskiprows );
  147.    glGetIntegerv( GL_PACK_SKIP_PIXELS, &packskippixels );
  148.  
  149.    /* Allocate storage for intermediate images */
  150.    tempin = (GLfloat *) malloc( widthin * heightin
  151.                     * components * sizeof(GLfloat) );
  152.    if (!tempin) {
  153.       return GLU_OUT_OF_MEMORY;
  154.    }
  155.    tempout = (GLfloat *) malloc( widthout * heightout
  156.                       * components * sizeof(GLfloat) );
  157.    if (!tempout) {
  158.       free( tempin );
  159.       return GLU_OUT_OF_MEMORY;
  160.    }
  161.  
  162.  
  163.    /*
  164.     * Unpack the pixel data and convert to floating point
  165.     */
  166.  
  167.    if (unpackrowlength>0) {
  168.       rowlen = unpackrowlength;
  169.    }
  170.    else {
  171.       rowlen = widthin;
  172.    }
  173.    if (sizein >= unpackalignment) {
  174.       rowstride = components * rowlen;
  175.    }
  176.    else {
  177.       rowstride = unpackalignment/sizein
  178.             * CEILING( components * rowlen * sizein, unpackalignment );
  179.    }
  180.  
  181.    switch (typein) {
  182.       case GL_UNSIGNED_BYTE:
  183.      k = 0;
  184.      for (i=0;i<heightin;i++) {
  185.         GLubyte *ubptr = (GLubyte *) datain
  186.                        + i * rowstride
  187.                + unpackskiprows * rowstride
  188.                + unpackskippixels * components;
  189.         for (j=0;j<widthin*components;j++) {
  190.                dummy(j, k);
  191.            tempin[k++] = (GLfloat) *ubptr++;
  192.         }
  193.      }
  194.      break;
  195.       case GL_BYTE:
  196.      k = 0;
  197.      for (i=0;i<heightin;i++) {
  198.         GLbyte *bptr = (GLbyte *) datain
  199.                      + i * rowstride
  200.              + unpackskiprows * rowstride
  201.              + unpackskippixels * components;
  202.         for (j=0;j<widthin*components;j++) {
  203.                dummy(j, k);
  204.            tempin[k++] = (GLfloat) *bptr++;
  205.         }
  206.      }
  207.      break;
  208.       case GL_UNSIGNED_SHORT:
  209.      k = 0;
  210.      for (i=0;i<heightin;i++) {
  211.         GLushort *usptr = (GLushort *) datain
  212.                         + i * rowstride
  213.                 + unpackskiprows * rowstride
  214.                 + unpackskippixels * components;
  215.         for (j=0;j<widthin*components;j++) {
  216.                dummy(j, k);
  217.            tempin[k++] = (GLfloat) *usptr++;
  218.         }
  219.      }
  220.      break;
  221.       case GL_SHORT:
  222.      k = 0;
  223.      for (i=0;i<heightin;i++) {
  224.         GLshort *sptr = (GLshort *) datain
  225.                       + i * rowstride
  226.               + unpackskiprows * rowstride
  227.               + unpackskippixels * components;
  228.         for (j=0;j<widthin*components;j++) {
  229.                dummy(j, k);
  230.            tempin[k++] = (GLfloat) *sptr++;
  231.         }
  232.      }
  233.      break;
  234.       case GL_UNSIGNED_INT:
  235.      k = 0;
  236.      for (i=0;i<heightin;i++) {
  237.         GLuint *uiptr = (GLuint *) datain
  238.                       + i * rowstride
  239.               + unpackskiprows * rowstride
  240.               + unpackskippixels * components;
  241.         for (j=0;j<widthin*components;j++) {
  242.                dummy(j, k);
  243.            tempin[k++] = (GLfloat) *uiptr++;
  244.         }
  245.      }
  246.      break;
  247.       case GL_INT:
  248.      k = 0;
  249.      for (i=0;i<heightin;i++) {
  250.         GLint *iptr = (GLint *) datain
  251.                     + i * rowstride
  252.             + unpackskiprows * rowstride
  253.             + unpackskippixels * components;
  254.         for (j=0;j<widthin*components;j++) {
  255.                dummy(j, k);
  256.            tempin[k++] = (GLfloat) *iptr++;
  257.         }
  258.      }
  259.      break;
  260.       case GL_FLOAT:
  261.      k = 0;
  262.      for (i=0;i<heightin;i++) {
  263.         GLfloat *fptr = (GLfloat *) datain
  264.                       + i * rowstride
  265.               + unpackskiprows * rowstride
  266.               + unpackskippixels * components;
  267.         for (j=0;j<widthin*components;j++) {
  268.                dummy(j, k);
  269.            tempin[k++] = *fptr++;
  270.         }
  271.      }
  272.      break;
  273.       default:
  274.      return GLU_INVALID_ENUM;
  275.    }
  276.  
  277.  
  278.    /*
  279.     * Scale the image!
  280.     */
  281.  
  282.    sx = (GLfloat) widthin / (GLfloat) widthout;
  283.    sy = (GLfloat) heightin / (GLfloat) heightout;
  284.  
  285. /*#define POINT_SAMPLE*/
  286. #ifdef POINT_SAMPLE
  287.    for (i=0;i<heightout;i++) {
  288.       GLint ii = i * sy;
  289.       for (j=0;j<widthout;j++) {
  290.      GLint jj = j * sx;
  291.  
  292.      GLfloat *src = tempin + (ii * widthin + jj) * components;
  293.      GLfloat *dst = tempout + (i * widthout + j) * components;
  294.  
  295.      for (k=0;k<components;k++) {
  296.         *dst++ = *src++;
  297.      }
  298.       }
  299.    }
  300. #else
  301.    if (sx<1.0 && sy<1.0) {
  302.       /* magnify both width and height:  use